package com.yifeng.repo.base.utils.codec;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * Created by daibing on 2019/2/26.
 */
public class URLEncodeHelper {

    /**
     * 正常编码
     */
    public static String encode(String value) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String encode(String value, String enc) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        try {
            return URLEncoder.encode(value, enc);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RFC3986 规则
     */
    public static String percentEncode(String value) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.name())
                    .replace("+", "%20")
                    .replace("*", "%2A")
                    .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RFC3986 规则
     */
    public static String splitEncode(String body, String paramsSeparator, String propertySeparator) {
        Map<String, String> map = Splitter.on(paramsSeparator).withKeyValueSeparator(propertySeparator).split(body);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            sb.append(percentEncode(entry.getKey()))
                    .append(propertySeparator)
                    .append(percentEncode(entry.getValue()))
                    .append(paramsSeparator);
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static String decode(String value) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        try {
            return URLDecoder.decode(value, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String decode(String value, String enc) {
        if (Strings.isNullOrEmpty(value)) {
            return null;
        }
        try {
            return URLDecoder.decode(value, enc);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }


}
